#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5+10;

#define in read()
typedef long long ll;

int mod,n,m,a[MAXN];
ll pl[MAXN<<2],mu[MAXN<<2],val[MAXN<<2];

int read(){
	int x = 0,sgn = 1;char ch = getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') sgn=-1;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
	return x*sgn;
}

void build(int o = 1,int l = 1,int r = n){
	mu[o] = 1;
	if(l == r) {
		val[o] = a[l] % mod;
		return;
	}
	int mid = l+r>>1;
	build(o<<1,l,mid);build(o<<1|1,mid+1,r);
	val[o] = (val[o<<1] + val[o<<1|1]) % mod;
	return;
}

void pushdown(int o,int l,int r){
	if(mu[o] != 1){
		val[o<<1] = mu[o] * val[o<<1] % mod;
		val[o<<1|1] = mu[o] * val[o<<1|1] % mod;
		mu[o<<1] = mu[o] * mu[o<<1] % mod;
		mu[o<<1|1] = mu[o] * mu[o<<1|1] % mod;
		pl[o<<1] = pl[o<<1] * mu[o] % mod;
		pl[o<<1|1] = pl[o<<1|1] * mu[o] % mod;
		mu[o] = 1;
	}
	if(pl[o] != 0){
		int mid = l+r>>1;
		val[o<<1] = (val[o<<1] + (ll)(mid-l+1) * pl[o]) % mod;
		val[o<<1|1] = (val[o<<1|1] + (ll)(r-mid) * pl[o]) % mod;
		pl[o<<1] = (pl[o] + pl[o<<1]) % mod;
		pl[o<<1|1] = (pl[o] + pl[o<<1|1]) % mod;
		pl[o] = 0;
	}
}
	
void add(int xl,int xr,int v,int o = 1,int l = 1,int r = n){
	if(l == xl && r == xr){
		val[o] = (val[o] + (ll)v * (r-l+1) % mod) % mod;
		pl[o] = (pl[o] + v) % mod;
		return;
	}
	pushdown(o,l,r);
	int mid = l+r>>1;
	if(xr <= mid) add(xl,xr,v,o<<1,l,mid);
	else if(xl > mid) add(xl,xr,v,o<<1|1,mid+1,r);
	else add(xl,mid,v,o<<1,l,mid),add(mid+1,xr,v,o<<1|1,mid+1,r);
	val[o] = (val[o<<1] + val[o<<1|1]) % mod;
}

void mul(int xl,int xr,int v,int o = 1,int l = 1,int r = n){
	if(l == xl && r == xr){
		val[o] = val[o] * v % mod;
		pl[o] = pl[o] * v % mod;
		mu[o] = mu[o] * v % mod;
		return;
	}
	pushdown(o,l,r);
	int mid = l+r>>1;
	if(xr <= mid) mul(xl,xr,v,o<<1,l,mid);
	else if(xl > mid) mul(xl,xr,v,o<<1|1,mid+1,r);
	else mul(xl,mid,v,o<<1,l,mid),mul(mid+1,xr,v,o<<1|1,mid+1,r);
	val[o] = (val[o<<1] + val[o<<1|1]) % mod;
}

ll query(int xl,int xr,int o = 1,int l = 1,int r = n){
	if(xl == l && xr == r) return val[o] % mod;
	int mid = l+r>>1;
	pushdown(o,l,r);
	if(xr <= mid) return query(xl,xr,o<<1,l,mid);
	else if(xl > mid) return query(xl,xr,o<<1|1,mid+1,r);
	else return (query(xl,mid,o<<1,l,mid) + query(mid+1,xr,o<<1|1,mid+1,r)) % mod;
}

int main (){
	n = in,m = in,mod = in;
	for(int i = 1;i <= n;i++) a[i] = in;
	build();
	while(m--){
		int op = in,x = in,y = in;
		switch(op){
		case 1:
			mul(x,y,in);
			break;
		case 2:
			add(x,y,in);
			break;
		case 3:
			printf("%lld\n",query(x,y)%mod);
			break;
		}
	}
	return 0;
}
